(() => {
    // 1.泛型类
    class GetMin<T>{
        list: T[] = []
        add(min: T) {
            this.list.push(min)
        }
        getMin(): T {
            let minNum = this.list[0]
            for (var i = 0; i < this.list.length; i++) {
                if (minNum > this.list[i]) {
                    minNum = this.list[i]
                }
            }
            return minNum
        }
    }
    let getMin = new GetMin<number>()
    getMin.add(1)
    getMin.add(4)
    getMin.add(0)
    console.log(getMin.getMin());


    // 2.泛型约束
    interface LengthWise {
        length: number
    }
    // 接口继承接口
    function identity1<T extends LengthWise>(args: T): T {
        console.log(args.length);
        return args
    }

    // 3.泛型约束
    type LengthWise2 = string
    // 接口继承类型
    function identity2<T extends LengthWise2>(args: T): T {
        console.log(args.length);
        return args
    }

    // 4.泛型约束
    interface LengthWise3 {
        length: number
    }
    // 混合
    type LengthWise4 = string | LengthWise3
    function identity3<T extends LengthWise4>(args: T): T {
        console.log(args.length);
        return args
    }


    // 5.keyof操作符
    class Person {
        name: string
        age: number
        sex: string
    }
    type K1 = keyof Person   // 'name' | 'age' | 'sex' 类型
    type K2 = keyof Person[] // 'length' | 'toString' | .....   Array构造函数上的键名
    type K3 = keyof {}       // sting | number   对象的键名是string或number类型

    function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
        return obj[key]
    }
    let obj = {
        x: 1,
        y: 2,
        z: 3
    }
    getProperty(obj, 'x')
    // 报错，obj上没有m键名
    // getProperty(obj, 'm')
})()